using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace GDFlacTools.Controls.SimpleLine
{

	#region Enums.

	public enum LineStyle
	{
		None = 0, 
		Vertical = 1,
		Horizontal = 2, 
		Box = 3
	}
	public enum GradientDirection
	{
		Horizontal = 1, 
		Vertical = 2
	}

	#endregion

	/// <summary>
	/// Summary description for UserControl1.
	/// </summary>
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] 
	public class SimpleLine : UserControl
	{

		#region Declarations.

		private Color _color = Color.Black ;
		private Color _fillColor = Color.Transparent ;
		private int _lineWidth = 1 ;
		private LineStyle _lineStyle ;
		private bool _fitToParent;
		private Color _gradient = Color.Transparent ;
		private bool _useGradient;
		private GradientDirection _gradientAngle = GradientDirection.Horizontal ;

		// Added AfterPaint event, which will be raised after the control paints itself
		public event PaintEventHandler AfterPaint;

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private readonly Container _components;

		#endregion

		#region Constructor.

        //public SimpleLine()
        //{
            
        //}

		public SimpleLine(Container components)
		{
		    _components = components;
		    // This call is required by the Windows.Forms Form Designer.
			InitializeComponent();
			//DrawLine() ;
			// TODO: Add any initialization after the InitComponent call
		}
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if( _components != null )
					_components.Dispose();
			}
			base.Dispose( disposing );
		}

		#endregion

		#region Properties.

		/// <summary>
		/// Enum indicating horizontal or vertical gradient draw
		/// </summary>
		[Category("Custom")]
		public GradientDirection GradientAngle
		{
			get { return _gradientAngle ; }
			set 
			{ 
				_gradientAngle = value ; 
				DrawLine() ;
			}
		}

		/// <summary>
		/// For lines, this will scale the line to fit right-to-left, or top-to-bottom
		/// </summary>
		[Category("Custom")]
		public bool FitToParent
		{
			get { return _fitToParent ; }
			set
			{
				_fitToParent = value ;
				DrawLine() ;
			}
		}

		/// <summary>
		/// If set to true, gradient will draw with FillColor and Gradient color
		/// </summary>
		[Category("Custom")]
		public bool UseGradient
		{
			get { return _useGradient ; }
			set
			{
				_useGradient = value ;
				DrawLine() ;
			}
		}

		[Category("Custom")]
		public Color FillColor
		{
			get { return _fillColor ; }
			set 
			{ 
				_fillColor = value ; 
				DrawLine() ;
			}
		}

		[Category("Custom")]
		public Color Gradient
		{
			get { return _gradient ; }
			set 
			{ 
				_gradient = value ; 
				DrawLine() ;
			}
		}

		[Category("Custom")]
		public Color LineColor
		{
			get 
			{ 
				if (_color == Color.Transparent) {_color = Parent.BackColor ; }
			return _color ; 
			
			}
			set 
			{ 
				_color = value ; 
				DrawLine() ;
			}
		}

		[Category("Custom")]
		public int LineWidth
		{
			get { return _lineWidth ; }
			set 
			{ 
				_lineWidth = value ; 
				DrawLine() ;
			}
		}

		/// <summary>
		/// Enum indicating horizontal line, vertical line, or Box
		/// </summary>
		[Category("Custom")]
		public LineStyle Style
		{
			get { return _lineStyle ; }
			set 
			{ 
				_lineStyle = value ;
				if (value == LineStyle.Vertical && Height <= LineWidth) { Height = 50 ; Width = LineWidth ;}
				if (value == LineStyle.Horizontal && Width <= LineWidth) { Width = 50 ; Height = LineWidth ; }
				if ((value == LineStyle.Box) && ((Width <= LineWidth) || (Height <= LineWidth)))
				{
					Height = 50 ;
					Width = 50 ; 
				}
				DrawLine() ;
			}
		}

		#endregion

		#region Events.

		protected override void InitLayout()
		{
			DrawLine() ;
		}

		#endregion

		#region Methods.

		public void DrawLine()
		{
			if (Parent == null) { return ; } //we don't want the control to draw on itself at design time

			if (Style == LineStyle.None) //default to Horizontal line, when placed on a parent
			{ 
				_lineStyle = LineStyle.Horizontal ; 
				_lineWidth = 1 ;
				Left = (Parent.Width /2)  - Width / 2 ;
				Top = Parent.Height / 2 ;
			}

			Graphics g = CreateGraphics() ; //create the graphics object
			g.Clear(Parent.BackColor) ;
			Pen pn ;
			if (Style == LineStyle.Vertical || Style == LineStyle.Horizontal)
				pn = new Pen( LineColor,LineWidth * 2); 
			else
				pn = new Pen( LineColor,LineWidth); 

			var pt1 = new Point( 0, 0 ); 
			Point pt2 ;
			if (Style == LineStyle.Horizontal) 
			{
				if (FitToParent) 
				{
					Left = 0 ;
					Width = Parent.ClientRectangle.Width ;
				}

				Height = LineWidth ;
				if (Height < 1) { Height = 1 ; }

				pt2 = new Point( Width , 0 ); 
				if (UseGradient == false)
				{
					g.DrawLine( pn, pt1, pt2 ); 

				}
				else
				{
					var rect = new Rectangle(new Point(0,0),new Size(ClientRectangle.Width,LineWidth)) ;
					if (FillColor == Color.Transparent) {FillColor = Parent.BackColor ; }
					{
						var lgb = new LinearGradientBrush(rect,FillColor,Gradient,0,false) ;
						g.FillRectangle(lgb,0,0,Width,LineWidth) ;
					}
				}
			}
			else if (Style == LineStyle.Vertical)
			{
				if (FitToParent)
				{
					Top = 0 ;
					Height = Parent.Height ;
				}

				Width = LineWidth   ;
				if (Width < 1) { Width = 1 ; }

				pt2 = new Point( 0, Height ) ; 
				if (UseGradient == false)
				{
					g.DrawLine( pn, pt1, pt2 ); 
				}
				else
				{
					var rect = new Rectangle(new Point(0,0),new Size(LineWidth,Height)) ;
					if (FillColor == Color.Transparent) {FillColor = Parent.BackColor ; }
				{
					var lgb = new LinearGradientBrush(rect,FillColor,Gradient,90,false) ;
					g.FillRectangle(lgb,0,0,LineWidth,Height) ;
						
				}
				}
			}
			else if (Style == LineStyle.Box ) 
			{
				if (FitToParent)
				{
					Top = 0 ;
					Left = 0 ;
					Width = Parent.Width;
					Height = Parent.Height ;
				}

				var rect = new Rectangle(new Point(0,0),new Size(Width, Height)) ;
				if (FillColor == Color.Transparent) {FillColor = Parent.BackColor ; }
				if (UseGradient)
				{
					var lgb = new LinearGradientBrush(rect,FillColor,Gradient,GradientAngle==GradientDirection.Horizontal ? 0 : 90,false) ;
					g.FillRectangle(lgb,0,0, Width - LineWidth, Height - LineWidth) ;

				}
				else
				{
					var sb = new SolidBrush(FillColor) ;
					g.FillRectangle(sb,0,0, Width - LineWidth, Height - LineWidth) ;

				}

				decimal mod = Decimal.Remainder(LineWidth, 2) ;
				int offset = 0 ;
				if (mod != 0 && LineWidth !=1) { offset = 1 ; }

				rect.Offset(LineWidth/2,LineWidth/2) ;
				rect.Height = rect.Height - LineWidth + offset -1 ;
				rect.Width = rect.Width - LineWidth + offset -1 ;
				if (LineWidth > 0) {g.DrawRectangle(pn,rect) ;}
			}
			
			g.Dispose() ;
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			OnResize(EventArgs.Empty) ;

			// Added AfterPaint event, which will be raised after the control paints itself
			if (AfterPaint != null)
				AfterPaint(this, e);
		}

		protected override void OnResize(EventArgs e)
		{
			DrawLine() ;
			base.OnResize (e);
		}

        #endregion

		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// simpleLine
			// 
			this.Name = "simpleLine";
			this.Size = new System.Drawing.Size(96, 32);

		}
		#endregion
	}
}
